#include "trimmer.h"

#include <algorithm> 
//#include <functional> 
#include "unaryFunctions.h"


trimmer::trimmer() : m_outputStatus( trimmer::UNDEFINED ) {

  // do nothing
}



std::string trimmer::trim(  std::string line, trimmer::stripMode direction ) {

  std::string result;
  result.clear();

  // empty input
  if ( line.size()==0 ) {
    m_outputStatus = trimmer::EMPTY_INPUT;
    return result;
  } // return an empty string, and existStatus=EMPTY_INPUT



  // check direction
  if ( direction!= trimmer::FRONT && direction!= trimmer::BACK && direction!= trimmer::BOTH ) {
   m_outputStatus = trimmer::WRONG_DIRECTION;
   return result;
  } // return an empty string, and existStatus=WRONG_DIRECTION


  if ( direction == trimmer::FRONT ) {
    result = leftTrim( line );
    m_outputStatus = trimmer::FRONT_DIRECTION;
  }

  else if ( direction == trimmer::BACK ) {
    result = rightTrim( line );
    m_outputStatus = trimmer::BACK_DIRECTION;
  }

  else if ( direction == trimmer::BOTH ) {
    result = rightTrim( leftTrim(line) );
    m_outputStatus = trimmer::BOTH_DIRECTION;
  }

  return result;

}


// the following implementation are taken from:
//    http://stackoverflow.com/questions/216823/whats-the-best-way-to-trim-stdstring
//    and hidden in the private part of the class

std::string trimmer::leftTrim( std::string in ) {

  std::string out=in;
  std::string::iterator pos;
  // isNotSpace comes from the unaryFunctions header
  pos = std::find_if(out.begin(), out.end(), isNotSpace );
  out.erase( out.begin(), pos );
  return out;
}


std::string trimmer::rightTrim( std::string in ) {

  std::string out=in;
  std::reverse( out.begin(), out.end() );

  out = leftTrim(out);
  std::reverse( out.begin(), out.end() );


// the same result could be reached with the following lines:
/*
  std::string out=in;
  std::string::reverse_iterator pos;
  pos = std::find_if(out.rbegin(), out.rend(), isNotSpace );
  out.erase( pos.base(), out.end() );
*/

  return out;
}


